<?php

namespace catchAdmin\logistics\controller;

use catchAdmin\customs\excel\clearFinishOrderExport;
use catchAdmin\customs\excel\clearFinishOrderGoodsExport;
use catchAdmin\customs\excel\clearOrderExport;
use catchAdmin\customs\excel\clearOrderGoodsExport;
use catchAdmin\customs\excel\orderExport;
use catchAdmin\customs\excel\orderGoodsExport;
use catchAdmin\customs\model\OrderSon as OrderSonModel;
use catcher\base\CatchRequest as Request;
use catcher\CatchAuth;
use catcher\CatchResponse;
use catcher\base\CatchController;
use catchAdmin\logistics\model\Sinotrans as SinotransModel;
use catcher\library\excel\Excel;
use catcher\library\excel\reader\Reader;
use think\Response;
use think\facade\Db;
use think\response\Json;
use catcher\Code;

class Sinotrans extends CatchController
{
    
    protected $sinotransModel;
    
    /**
     *
     * @time 2021/11/25 11:43
     * @param SinotransModel $sinotransModel
     * @return mixed
     */
    public function __construct(SinotransModel $sinotransModel)
    {
        $this->sinotransModel = $sinotransModel;
    }
    
    /**
     *
     * @time 2021/11/25 11:43
     * @return Response
     */
    public function index() : Response
    {
        return CatchResponse::paginate($this->sinotransModel->getList());
    }
    
    /**
     *
     * @time 2021/11/25 11:43
     * @param Request $request
     * @return Response
     */
    public function save(Request $request) : Response
    {
         return CatchResponse::success($this->sinotransModel->storeBy($request->post()));
    }
    
    /**
     *
     * @time 2021/11/25 11:43
     * @param $id
     * @return Response
     */
    public function read($id) : Response
    {
         return CatchResponse::success($this->sinotransModel->findBy($id));
    }
    
    /**
     *
     * @time 2021/11/25 11:43
     * @param $id
     * @param Request $request
     * @return Response
     */
    public function update($id, Request $request) : Response
    {
         return CatchResponse::success($this->sinotransModel->updateBy($id, $request->post()));

    }
    
    /**
     *
     * @time 2021/11/25 11:43
     * @param $id
     * @return Response
     */
    public function delete($id) : Response
    {
         return CatchResponse::success($this->sinotransModel->deleteBy($id));
    }

     /**
     *
     * @time 2021/11/03 14:02
     * 中外运推送
     * @param Request $request
     * @return Json
     */
    public function sinotransPush(Request $request,CatchAuth $auth) : Response
    {

        $orderId = $request->post('orderId');
        if(!$orderId){
             return CatchResponse::fail('缺少参数');
        }
        //订单表
        //非管理员要商户id
        $user = $auth->user();
        if($user['type'] !== 1 ){
            $where[] = ['tenant_id','=',$user['tenant_id']];
        }
        $where[] = ['orderId','in',$orderId];
        $where[] = ['status','=',0];
        $where[] = ['deleteStatus','=',0];
        $orderInfo = Db::name('db_customs_order')->field('id,orderId,userId,amount,distributionfee,tax,realPayment,contactAddr,detailAddr,contactName,payOrderNo,buyerName,ConsigneeCode,contactMobile,snum,NetWeight,ebpCode,ebpName,paycomCode,paycomName,task_no,discount,guid,contactCode,express_no')->where($where)->select();
        
        //订单子表
        $where1[] = ['orderId','in',$orderId];
        $where1[] = ['deleteStatus','=',0];
        $ordersonInfo = Db::name('db_customs_orderlist')->field('orderId,productId,productName,barcode,num,weight,price,business_addr,GModel,Unit,spec_qty,rough_weight')->where($where1)->select();
        if(!$orderInfo){
            return CatchResponse::fail('没有该订单');
        }

        if(!$ordersonInfo){
             return CatchResponse::fail('该订单,没有商品信息');
        }

        $order = [];
        $order['ObjectCode'] = 'CES_ORDER_SYNC';
        $order['InterfaceCode'] = 'HLCES';
        $order['MessageDetail'] = [];
        $order['MessageDetail']['ServiceType'] = 'CbecOrderSync';
        $order['MessageDetail']['ServiceData'] = [];

        $orderArr = [];
        foreach($orderInfo as $key => $value){
            if(empty($value['express_no'])){
                return CatchResponse::fail($value['orderId'] . '订单，没有快递信息');
            }
            $ordersonInfo = OrderSonModel::field('orderId,RecordMaterialNo,barcode,num,spec_qty,price')
                ->where(['orderId'=>$value['orderId'],'deleteStatus'=>0])
                ->select()
                ->each(function (&$item){
                    $where['deleted_at'] = 0;
                    $where['barcode'] = $item['barcode'];
                    if(!empty($item['RecordMaterialNo'])){
                        $where['record_material_no'] = $item['RecordMaterialNo'];
                    }

                    $material_info = Db::name('db_customs_record_material')->field('net_weight,gross_weight,origin_country_code,trade_country_code,currency_code,g_code,g_model,g_name,currency_code,unit,unit1,unit2,qty1,qty2,record_material_no')->where($where)->find();
                    if ($material_info){
                        foreach ($material_info as $key => $value){
                            $item[$key] = $value;
                        }
                    }else{
                        $item = false;
                    }
                })
                ->toArray();

            if(!$ordersonInfo){
                return CatchResponse::fail($value['orderId'] . '订单，没有商品信息');
            }
            $isNull = array_search(null,$ordersonInfo);//看是否有null
            if($isNull !== false){
                return CatchResponse::fail($value['orderId'] . '订单，第'.($isNull+1).'项商品没有账册信息');
            }
             //订单集合
            $orderlist = [];
            $orderlist['comUnitCode'] = '20191022';  //商务单元代码
            $orderlist['ownerName'] = 'shishaozhong';//下单人名
            //$orderlist['comUnitCode'] = 'kujing1';  //测试商务单元代码
            //$orderlist['ownerName'] = 'kjdshang';  //测试商务单元代码
            $orderlist['customerProjectCode'] = 'NJGDMM_SOUTH_1210'; //所属项目代码
            $orderlist['ddOrderBizType'] = 'SAL';   //订单业务类型
            $orderlist['ddOrderBizNature'] = 'IMP'; //订单业务性质
            $orderlist['ddOrderOpType'] = ''; //订单操作类型
            $orderlist['ddUrgencyDegree'] = '';//紧急程度
            $orderlist['ddDeliveryMode'] = '';//配送方式
            $orderlist['ddPayTimeType'] = ''; //结算方式
            $orderlist['orderNo'] = $value['orderId'];//订单编号
            $orderlist['requireArriveDate'] = '';//要求到货时间
            $orderlist['goodsAmount'] = '';//商品总金额
            $orderlist['incidentalAmount'] = $value['distributionfee'];//运杂费金额
            $orderlist['insuranceAmount'] = '';//保费金额
            $orderlist['discountAmount'] = '';//抵扣金额
            $orderlist['taxAmount'] = $value['tax'];//企业预先代扣的税款金额
            $orderlist['orderAmount'] = $value['realPayment'];//订单实付金额
            $orderlist['ddCurrencyKind'] = 'CNY';//币种
            $orderlist['goodsTotalQty'] = $value['snum'];//商品总数量
            $orderlist['ddOrderState'] = '';//订单状态
            $orderlist['ddPaymentState'] = '';//支付状态
            $orderlist['note'] = '';//备注
            $orderlist['opType'] = '';//订单导入类型
            $orderlist['goodsInfo'] = $value['orderId'];//货品信息
            $orderlist['requireInsuranceSign'] = '';//是否保险

            //订单项列表
            $orderSonArr = [];
            $netWeight = 0;
            $grossWeight = 0;
            foreach($ordersonInfo as $k => $v){
                 $v['num'] = (int)($v['num'] * $v['spec_qty']);
                 $v['price'] = round($v['price']/$v['spec_qty'],2);

                 $orderson = [];
                 $orderson['fkSku'] = ''; //sku外键
                 $orderson['skuCode'] = $v['barcode']; //sku编码
                 $orderson['itemNo'] = $k+1; //订单项编号(数字，按1、2、3顺序填写)
//                 $orderson['skuName'] = $v['g_name']; //sku名称
//                 $orderson['model'] = $v['g_model']; //型号
//                 $orderson['specification'] = $v['g_model']; //规格参数
                 $orderson['skuName'] = ''; //sku名称
                 $orderson['model'] = ''; //型号
                 $orderson['specification'] = ''; //规格参数
                 $orderson['qty'] = $v['num']; //商品数量
                 $orderson['unitPrice'] = $v['price']; //商品单价
                 $orderson['taxRate'] = ''; //税率
                 $orderson['unitPriceWithTax'] = ''; //含税单价
                 $orderson['amount'] = ''; //总金额
                 $orderson['taxAmount'] = ''; //税额
                 $orderson['amountWithTax'] = ''; //含税总额
                 $orderson['ddCurrencyKind'] = 'CNY'; //币种
                 $orderson['unitGrossWeight'] = $v['gross_weight']; //单位毛重
                 $orderson['unitNetWeight'] = $v['net_weight'];//单位净重
                 $netWeight += $v['num']*$v['net_weight']; //总毛重
                 $grossWeight += $v['num']*$v['gross_weight'];//总净重
                 $orderSonArr[] = $orderson;
            }
            $orderlist['grossWeight'] = round($grossWeight,5);//总净重
            $orderlist['netWeight'] = round($netWeight,5);//总毛重

            $orderlist['orderItems'] = $orderSonArr;
            // 订单收货地址
            $orderAddressCebc = [];
            $provinceName = explode('-',$value['contactAddr']);
            $orderAddressCebc['provinceName'] = $provinceName[0]; //省名称
            $orderAddressCebc['cityName'] = $provinceName[1]; //地市名称
            $orderAddressCebc['provinceName'] = $provinceName[2]; //县区名称
            $orderAddressCebc['detailAddress'] = $value['detailAddr']; //详细地址
            $orderAddressCebc['ddContactIdType'] = 'RIC'; //收货人证件类型
            $orderAddressCebc['contactIdCode'] = $value['contactCode']; //收货人证件号
            $orderAddressCebc['contactName'] = $value['contactName']; //收货人名
            $orderAddressCebc['contactTel'] = $value['contactMobile'];; //收货人电话
            $orderAddressCebc['contactMobile'] = $value['contactMobile']; //收货人手机号
            $orderAddressCebc['postCode'] = ''; //邮编
            $orderlist['orderAddressCebc'] = $orderAddressCebc;
            // 订单订购人地址
            $orderAddressPch = [];
            $orderAddressPch['provinceName'] = ''; //省名称
            $orderAddressPch['cityName'] = ''; //地市名称
            $orderAddressPch['provinceName'] = ''; //县区名称
            $orderAddressPch['detailAddress'] = '';; //详细地址
            $orderAddressPch['ddContactIdType'] = 'RIC'; //订购人证件类型
            $orderAddressPch['contactIdCode'] = $value['ConsigneeCode']; //订购人证件号
            $orderAddressPch['contactName'] = $value['buyerName'];; //订购人名
            $orderAddressPch['contactTel'] = $value['contactMobile'];; //订购人电话
            $orderAddressPch['contactMobile'] = $value['contactMobile'];; //订购人手机号
            $orderAddressPch['postCode'] = ''; //邮编
            $orderlist['orderAddressPch'] = $orderAddressPch;
            // 快递单号
            $expressWebInfo = [];
            $expressWebInfo['expressWebNo'] = $value['express_no']; //快递单号
            $orderlist['expressWebInfo'] = $expressWebInfo;
            $orderArr[] = $orderlist;
        }
        $order['MessageDetail']['ServiceData']['orderList'] = $orderArr;
        //$url = "http://apitest.cbec.y2t.com:8080/mtc-web/openAPI/adapter";//测试环境
        $url = 'api.cbec.y2t.com/mtc-web/openAPI/adapter'; //正式环境请求地址
        $news = $this->httprequest($url,$order);
        $content = json_encode($order,JSON_UNESCAPED_UNICODE)."\r\n".$news."\r\n";
        $this->writeLog('sinotrans',$content);
        $info  = json_decode($news,true);
        if($info['ResultCode'] === 'S'){
            if($info['ResultData']['code'] === 'S'){
                $successNum = 0;
                $successOrderNo  = '';
                $failNum = 0;
                $failOrderNo = '';
                $arr = $info['ResultData']['data'];
                foreach ($arr as $k1 => $v1){
                    $where2['orderId'] = $v1['orderNo'];
                    if($v1['code'] === 'S'){
                        //物流运单编号
                        $res = [];
                        $res['bill_no'] = $v1['logisticsWaybillNo'];
                        $res['waybill_status'] = 1;
                        $res['logistics_port'] = 2;
                        $res['error_msg'] = $v1['msg'];
                        $successNum += Db::name('db_customs_order')->where($where2)->save($res);
                        $successOrderNo .= $v1['orderNo']."订单推送成功";
                    }else{
                        if($v1['msg'] !== '该订单号已同步！'){
                            $res = [];
                            $res['waybill_status'] = 20;
                            $res['error_msg'] = $v1['msg'];
                            Db::name('db_customs_order')->where($where2)->save($res);
                        }
                        $failNum += 1;
                        $failOrderNo .= $v1['orderNo']."订单物流推送失败,原因(".$v1['msg'].")";
                    }
                }
                if($successNum > 0){
                    if($failNum > 0 && $successNum > 0){
                        return CatchResponse::fail($successOrderNo.$failOrderNo,Code::WARNING);
                    }
                    return CatchResponse::success([],$successOrderNo);
                }else{
                    return CatchResponse::fail($failOrderNo,Code::WARNING);
                }
            }else{
                 return CatchResponse::fail($info['ResultData']['msg']);
            }
        }else{
             return CatchResponse::fail($info['ResultContent']);
        }
    }
    //下载模板
    public function downTemplate(Request $request)
    {
        $filename = $request->post('name');
        $file = "export/template/{$filename}.xlsx";
        if (is_file($file)) {
            return CatchResponse::success(['url' => 'http://' . $_SERVER['HTTP_HOST'] . '/' . $file]);
        } else {
            return CatchResponse::fail('模板文件不存在');
        }

    }
    //上传
    public function importLogistics(Request $request)
    {
        // 获取表单上传文件
        $files = request()->file();
        try {
            //10M以下csv,xlsx,xls文件
            validate(['file' => 'fileSize:10485760|fileExt:csv,xlsx,xls'])
                ->check($files);
            $fields = [
                ['field' => 'orderId', 'label' => '订单号'],
                ['field' => 'express_company', 'label' => '快递公司'],
                ['field' => 'express_no', 'label' => '快递单号']
            ];
            $msg = [];
            $this->importExcl(array_column($fields, 'field'), $files['file'], function ($data) use ($fields, &$msg) {
                if (count($data) > 1) {
                    $now = date('Y-m-d H:i:s');
                    // 启动事务
                    Db::startTrans();
                    $success = 0;
                    foreach ($data as $key => $value) {
                        if ($key === 0) {
                            foreach ($fields as $k => $v) {
                                //验证表格头部是否模板字段
                                if (strpos($value[$v['field']], $v['label']) === false) {
                                    $msg = ['code' => 10001, 'message' => '模板表头' . $value[$v['field']] . '不匹配，请下载最新模板'];
                                    Db::rollback();
                                    return;

                                }
                            }
                        } else {
                            $where = [];
                            $params = [];
                            foreach ($fields as $k => $v) {
                                if ($k === 0) {
                                    if (empty($value[$v['field']])) {
                                        $msg = ['code' => 10001, 'message' => '第' . ($key + 1) . '行' . $v['label'] . '不能为空'];
                                        Db::rollback();
                                        return;
                                    }
                                    $where[$v['field']] = $value[$v['field']];
                                } else {
                                    $params[$v['field']] = $value[$v['field']];
                                }
                            }
                            $params['modifyTime'] = $now;
                            $res = Db::table('db_customs_order')->where($where)->save($params);
                            if (!$res) {
                                $msg = ['code' => 10002, 'message' => '第' . ($key + 1) . '行导入失败，请检查订单号'];
                                Db::rollback();
                                return;
                            } else {
                                $success++;
                            }
                        }
                    }
                    if ($success > 0) {
                        Db::commit();
                    } else {
                        Db::rollback();
                    }
                    $msg = ['code' => 10000, 'message' => '操作成功，成功导入' . $success . '条数据'];
                } else {
                    $msg = ['code' => 10002, 'message' => '没有需要导入的数据'];
                }
            });
            if ($msg['code'] === 10000) {
                return CatchResponse::success([], $msg['message']);
            } else {
                return CatchResponse::fail($msg['message']);
            }
        } catch (\think\exception\ValidateException $e) {
            return CatchResponse::fail($e->getMessage());
        }
    }

    /**
     * 导入
     * @param Reader $reader
     * @param $fields
     * @param $file
     * @return bool
     */
    public function importExcl($fields, $file, callable $callable)
    {
        $excel = new class($fields) extends Reader {
            protected $fields;

            public function __construct($fields)
            {
                $this->fields = $fields;
            }

            public function headers()
            {
                // TODO: Implement headers() method.
                return $this->fields;
            }
        };
        $excel->import($file)->then(function ($data) use ($callable) {
            $callable($data);
        });

    }
        /**
     *
     * @time 2021/11/03 14:02
     * url请求
     * @param string $url 文件夹类型
     * @param array $data 内容
     * @return string
     */
    protected function httprequest(string $url,array $data)
    {
        $ch = curl_init();//初始化
        //设置请求头信息
        $header = array(
              'Accept-Charset: utf-8',
              'Content-Type: application/json'
        );
        curl_setopt($ch, CURLOPT_HTTPHEADER, $header);

        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS ,stripslashes(json_encode($data,JSON_UNESCAPED_UNICODE)));

        //curl注意事项，如果发送的请求是https，必须要禁止服务器端校检SSL证书
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);//获取的信息以字符串返回
        $result = curl_exec($ch);
        curl_close($ch);
        return $result;
    }
    /**
     *
     * @time 2021/11/03 14:02
     * 日志
     * @param string $type 文件夹类型
     * @param string $content 内容
     * @return string
     */
    public function writeLog(string $type, string $content){
        $now = date('Y-m-d H:i:s');
        $ip = request()->ip();
        $log_path = 'log/customs/'.$type.'/';
        $destination = $log_path.date('Y-m-d').'.log';
        if(!is_dir($log_path)) {
            mkdir($log_path,0755,true);
        }
        error_log("[{$now}] ".$_SERVER['REMOTE_ADDR'].' '.$_SERVER['REQUEST_URI'].'  IP:'.$ip."\r\n{$content}\r\n", 3,$destination);
    }
}